#-*- coding: UTF-8 -*-

import time
from os import spawnv, P_WAIT

from turbogears import expose, identity, flash, validators, redirect, validate, controllers
from onlineapidoc.model import (Space, User, Template, Page, USDN_VER,
                                PAGE_TYPE_DIR, PAGE_TYPE_LINK, PAGE_TYPE_NORMAL_PAGE,
                                SPACE_STATUS_UNAVAILABLE,
                                lang_codes)
from onlineapidoc.utils import (get_cookie, set_cookie, jsback, get_space_family_lang, do_duplicate_page,
                                get_matching_lang_page)
from onlineapidoc.subcontrollers.page import PageController
from sqlobject.sqlbuilder import Delete, Update
from cherrypy import request
from sqlobject.main import SQLObjectNotFound
from ftplib import FTP

FTP_ADDR = "113.168.0.10"
FTP_PATH = "/Download/Doc/"
FTP_USER = "support"
FTP_PASS = "spt"

STATIC_ROOT = "D:\\Dev\\WebApps\\static\\"
STATIC_PAGE_DIR = "html\\pages\\"
STATIC_PAGE_EXT = ".html"

CHM_COMPILER = "D:\ProgramFiles\HTML Help Workshop\hhc.exe"

HHC_HEADER = """\
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
<meta name="GENERATOR" content="USDN V%s">
<!-- Sitemap 1.0 -->
</HEAD><BODY><UL>
""" % USDN_VER

HHC_ITEM_FILE = """\
<LI><OBJECT type="text/sitemap">
    <param name="Name" value="%(name)s">
    <param name="Local" value="%(href)s">
    <param name="ImageNumber" value="11">
</OBJECT></LI>
"""

HHC_ITEM_FOLDER = """\
<LI><OBJECT type="text/sitemap">
    <param name="Name" value="%(name)s">
    <param name="Local" value="%(href)s">
    <param name="ImageNumber" value="5">
</OBJECT></LI>
"""

HHC_FOOTER = """\
</UL></BODY></HTML>
"""

HHP_TEMPLATE = """\
[OPTIONS]
Contents File=%(hhc_file)s
Compiled File=%(chm_file)s
Index File=
Default Window=Main
Default Topic=%(main_page)s
Default Font=MS Sans Serif, 10,134
Full-text search=Yes
Auto Index=No
Language=0x804 Chinese (Simplified/PRC)
Title=%(spacename)s
Compatibility=1.1 or later
Binary TOC=No
Binary Index=Yes
Create CHI file=No
Error log file=_errorlog.txt
Full text search stop list file=
Display compile progress=Yes
Display compile notes=Yes

[WINDOWS]
Main="%(spacename)s","%(hhc_file)s",,,,,,,,0x51520,184,0x10187E,[139,82,958,700],0xB0000,,,,,,0

[FILES]
%(html_files)s
"""

class SpaceController(controllers.Controller):
    @expose()
    def default(self, *args, **kwargs):
        parts = request.path.rsplit('/')
        if len(parts) == 3 and parts[-1].isdigit():
            return self.space(parts[-1])
    
    
    @expose()
    def index(self, *args, **kwargs):        
        space_id = self._active_space_id()
        if space_id:
            raise redirect('/space/%s' % space_id)
        return self.locate()
    
    @expose()
    def new_space(self, name, description, language):
        admin = User.get(identity.current.user.id)
        space = Space(name=name,
                      description=description,
                      admin=admin,
                      parent_space=None,
                      language=int(language))
        
        raise redirect('/dashboard')
    
    @expose(template="onlineapidoc.templates.space.locate")
    def locate(self):
        all_spaces = Space.select("parent_space_id is NULL order by upper(name)")
        spaces = [space for space in all_spaces if not space.archived]
        
        return dict(active_section='space',
                    spaces=spaces)
    
    
    @expose(template="onlineapidoc.templates.space.index")
    @validate(validators=dict(space_id=validators.Int()))
    def space(self, space_id):
        space = Space.get(space_id)
        
        set_cookie('active_space_id', space_id)
        
        f_template = get_cookie('favorite_template', 0)
        
        templates = Template.select(orderBy='name')

        return dict(active_section='space',
                    space=space,
                    templates=templates,
                    page_path={},
                    favorite_template=int(f_template),
                    current_page=None,
                    lang_family = get_space_family_lang(space))
 
    @expose(template="onlineapidoc.templates.space.setting")
    def space_setting(self, space_id):
        space = Space.get(space_id)
        
        return dict(active_section='space', space=space)
    
    @expose()
    def space_setting_commit(self, name, status, description, id):
        space = Space.get(id)
        
        if space:
            space.set(name=name, status=int(status), description=description)
            raise redirect('/dashboard')
        else:
            flash(_("Can not find space!"))
            return jsback()

    @expose()
    def space_duplicate(self, space_id):
        """
        Make a copy from the space with content.
        """
        space = Space.get(space_id)
        self._do_duplicate_space(space, space.name+_("_copy"), True, None)

        raise redirect('/dashboard')
    
    @expose()
    def space_translate(self, space_id):
        """
        Make a copy from the space without content for translating.
        """
        space = Space.get(space_id)
        self._do_duplicate_space(space, space.name+_("_t_copy"), True, space)
        raise redirect('/dashboard')

    @expose()
    def space_delete(self, space_id):
        """
        Delete space by id.
        """
        space = Space.get(space_id)
        
        space.set(status=SPACE_STATUS_UNAVAILABLE)

        ##True delete operation
        #Page._connection.query(Page._connection.sqlrepr(Delete(Page.sqlmeta.table, Page.q.spaceID==space_id)))
        #space.destroySelf()
        
        raise redirect('/dashboard')

    @expose(template="onlineapidoc.templates.space.genchm")
    def space_chm(self, space_id):
        space = Space.get(space_id)
        
        return dict(active_section='space', space=space)
    
    @expose()
    def space_chm_commit(self, space_id, filename, main_page_id, rls_encode, rebuild_all=0, ext_info=0):
        """
        Generate the hhc & hhp files for space.
        """
        space = Space.get(space_id)
        space.set(rls_encode=rls_encode, rls_default_page=int(main_page_id))
        
        if ext_info:
            build_with_info = True
        else:
            build_with_info = False

        #build space before generating chm
        if rebuild_all:
            self._rebuild(space_id, build_with_info)
        else:
            self._build(space_id, build_with_info)

        self.hhc_content = ""
        self.hhp_html_files = []
        self.hhc_content += HHC_HEADER
        self.hhc_content += HHC_ITEM_FOLDER % {'name': space.name.encode(space.rls_encode, 'xmlcharrefreplace'), 'href': ""}
        self.hhc_content += "<UL>\n"

        for page in space.root_pages:
            self._gen_hhc_node(page, space.language, space.rls_encode)
            
        self.hhc_content += "</UL>\n"
        self.hhc_content += HHC_FOOTER

        #write hhc file
        fh = open(STATIC_ROOT + str(space.id) + ".hhc", "w+")
        fh.write(self.hhc_content)
        fh.close()
        
        #write hhp file
        if main_page_id:
            mp = STATIC_PAGE_DIR + str(main_page_id) + STATIC_PAGE_EXT
        else:
            mp = ""

        hhp_file = STATIC_ROOT + str(space.id) + ".hhp"
        fh = open(hhp_file, "w+")
        fh.write(HHP_TEMPLATE % {'hhc_file': str(space.id) + ".hhc",
                    'chm_file': filename.encode('gbk', 'xmlcharrefreplace') + ".chm",
                    'spacename': space.name.encode('gbk', 'xmlcharrefreplace'),
                    'html_files': '\n'.join(self.hhp_html_files),
                    'main_page': mp})
        fh.close()
        
        try:
            r = spawnv(P_WAIT, CHM_COMPILER, [hhp_file,hhp_file])
            if r != 1:
                flash(_("Some static file lost!"))
        except OSError,e:
            flash(str(e))

        ftp=FTP(FTP_ADDR, FTP_USER, FTP_PASS)
        
        ftp.cwd(FTP_PATH)
        bufsize = 1024
        st_filename=STATIC_ROOT+filename.encode('gbk', 'xmlcharrefreplace') + ".chm"
        file_handler = open(st_filename,'rb')
        ftp.storbinary('STOR ' + filename.encode('gbk', 'xmlcharrefreplace') + ".chm", file_handler, bufsize) #上传文件
        ftp.set_debuglevel(0)
        
        file_handler.close() #关闭文件
        ftp.quit()
        
        flash(_("Generate successfully! Download from: http://down.nlscan.com/Doc/") + filename + ".chm")
        
        raise redirect('/space/space_chm/'+space_id)

    def _build(self, space_id, info):
        """
        Generate the local files for all of unbuilt pages in the space.
        """
        space = Space.get(space_id)
        self._gen_local_pages(space.unbuilt_normal_pages, space.rls_encode, info)
        return None

    def _rebuild(self, space_id, info):
        """
        Generate the local files for all pages in the space.
        """
        space = Space.get(space_id)
        self._gen_local_pages(space.all_normal_pages, space.rls_encode, info)
        return None

    def _get_link_copy_by_space(self, main_page, space_id):
        for page in main_page.link_copies:
            if page.space.id == space_id:
                return page
        return None
    
    def _active_space_id(self):
        return int(get_cookie('active_space_id', 0))
    
    def _gen_local_pages(self, pages, codec, ext_info):
        """
        Generate static files in disk.
        """
        pagectrl = PageController()
        if pages:
            for page in pages:
                fh = open(STATIC_ROOT + STATIC_PAGE_DIR + str(page.id) + STATIC_PAGE_EXT, "wb+")
                fh.write(pagectrl.page_view_by_template(page.id, True, codec, ext_info))
                fh.close()
                page.set(built=True)
        return None
    
    def _do_duplicate_space(self, space, new_name, with_content, parent):
        """
        create new space as child of the exist one or None, and copy all of pages from parent to child.
        """
        new_space = Space(name=new_name,
                          description=space.description,
                          admin=space.admin,
                          parent_space=parent)
    
        for page in space.root_pages:
            do_duplicate_page(page, new_space, with_content, None)
    
        return None
    
    def _gen_hhc_node(self, page, lang, codec):
        if page.type == PAGE_TYPE_DIR:
            '''
            Is there index page of a directory
            '''
            if eval(page.content):
                '''
                find the index page by language version
                '''
                indexid = int(eval(page.content))
                try:
                    indexpage = Page.get(indexid)
                except SQLObjectNotFound:
                    hrefstr = ""
                else:
                    langpage = get_matching_lang_page(indexpage, lang)
                    if langpage:
                        hrefstr = STATIC_ROOT + STATIC_PAGE_DIR + str(langpage.id) + STATIC_PAGE_EXT
            else:
                hrefstr = ""

            self.hhc_content += HHC_ITEM_FOLDER % {'name': page.name.encode(codec, 'xmlcharrefreplace'), 'href': hrefstr}
            self.hhc_content += "<UL>\n"
            for sub_page in page.sub_pages:
                self._gen_hhc_node(sub_page, lang, codec)
            self.hhc_content += "</UL>\n"

        elif page.type == PAGE_TYPE_NORMAL_PAGE:
            self.hhc_content += HHC_ITEM_FILE % {'name': page.name.encode(codec, 'xmlcharrefreplace'),
                                'href': STATIC_ROOT + STATIC_PAGE_DIR + str(page.id) + STATIC_PAGE_EXT}
            self.hhp_html_files.append (STATIC_PAGE_DIR + str(page.id) + STATIC_PAGE_EXT)

        return None
